import { createActions, handleActions } from 'redux-actions';
import { actions as roleActions } from './role';
import { actions as tagActions } from './tag';
import { actions as noticeActions } from './notice';
import { actions as socketIOActions } from './socket-io';
import { actions as taskActions } from './task';
import { get, includes, find } from 'lodash';
import axios from 'axios';
import { getCert, getDeviceInfo } from '@api/cert';
import { MODULE_SPLIT } from '@util/constants';
import { message } from 'antd';
import setOem from '@util/set-oem';

const token = localStorage.getItem('token') || '';

const initState = {
  authed: false,
  certed: false,
  token: token,
  cert: {},
  deviceId: '',
  user: {
    // user_id: string
    // nickname: string
    // is_admin: string
    // access: [{
    //   module: string,
    //   power: [enum("create", "modify", "delete", "view")]
    // }]
    // accessMap: {
    //   [module:string]: [enum("create", "modify", "delete", "view")]
    // }
  }
};

let globalGetRunningTaskTimer = null;

export const actions = createActions({
  SET_AUTH: auth => dispatch => {
    const token = get(auth, 'token', '');
    const userId = get(auth, 'user.user_id', '');
    const access = get(auth, 'user.access', []);
    localStorage.setItem('token', token);
    axios.defaults.headers.common['b-json-web-token'] = token;

    // 清理获取任务数的timer
    if (globalGetRunningTaskTimer) {
      window.clearInterval(globalGetRunningTaskTimer);
    }

    if (token) {
      dispatch(tagActions.loadTags());

      if (includes(access, 'notice')) {
        dispatch(noticeActions.loadNotice());
      }
      const getJurisdiction = find(access, item => {
        return item.module === 'task-manage' && includes(item.power, 'view');
      });

      if (getJurisdiction) {
        dispatch(taskActions.getRunningTaskCount());

        // 轮询，每30s获取一次运行任务数
        globalGetRunningTaskTimer = setInterval(() => {
          dispatch(taskActions.getRunningTaskCount());
        }, 30000);
      }
      dispatch(socketIOActions.init({ token, userId }));
    }
    if (token) {
      dispatch(roleActions.getrolelist());
    }
    return auth;
  },
  GET_CERT: () => getCert(),
  GET_DEVICE_ID: () => getDeviceInfo({ type: 'lhash' })
});

const reducer = handleActions(
  {
    SET_AUTH: (state, action) => {
      const { error, payload } = action;
      const token = get(payload, 'token', '');
      const user = get(payload, 'user') || {};
      const access = get(user, 'access', []);
      if (user && Array.isArray(access)) {
        user.accessMap = get(user, 'access', []).reduce((map, current = {}) => {
          const { module: moduleType, power = [] } = current;

          if (!moduleType || typeof moduleType !== 'string') {
            return map;
          }
          map[moduleType] = power;
          // 将传递过来的二级模块权限解析出来加入到以及模块权限中，此处不做去重
          const topModuleType = get(moduleType.split(MODULE_SPLIT), '0');
          if (topModuleType && topModuleType !== moduleType) {
            if (!Array.isArray(map[topModuleType])) {
              map[topModuleType] = [];
            }
            map[topModuleType] = map[topModuleType].concat(power);
          }
          return map;
        }, {});
      }
      if (!error) {
        return {
          ...state,
          token,
          user,
          authed: true
        };
      }
      return { ...state, authed: true };
    },
    GET_CERT: (state, action) => {
      const { error, payload } = action;
      const cert = get(payload, 'data.data.result');
      if (cert) {
        const certModules = get(cert, 'modules', []);
        const isSlaveRole = ['slave', 'storage'].includes(get(cert, 'nodeRole'));
        cert.isSalve = includes(certModules, 'distribute') && isSlaveRole;
      }

      const expiredTime = get(payload, 'data.data.result.expiry_time', 0);
      const expired = Number(expiredTime) * 1000 < Number(get(payload, 'data.data.result.now', 0));
      if (expiredTime !== 0 && expired && !cert.isSalve) {
        message.warning('您的证书已过期');
      }
      setOem(payload);

      if (!error) {
        return {
          ...state,
          cert,
          certed: true
        };
      }
      return { ...state, certed: true };
    },
    GET_DEVICE_ID: (state, action) => {
      const { error, payload } = action;
      if (!error) {
        const deviceId = get(payload, 'data.data.result.lhash', '');
        return {
          ...state,
          deviceId
        };
      }
      return state;
    }
  },
  initState
);

export default reducer;
